(* ============================================================ *)
(* Parser - lexer pour l'analyse lexicale du protocole external *)
(* author Mathieu Barbin                                        *)
(* version 1.1.*                                                *)
(* ============================================================ *)

open BplibTypes

type protocole = BplibTypes.protocole_external

(** Lorsqu'on repond, il peut y avoir un code (asynchrone) *)
type reponse = BplibTypes.reponse_external


(** Fonctions de parsing du protocole external :
    renvoit None si erreur de syntaxe *)

let of_string s = 
  try
    let buff = Lexing.from_string s in
    Some (ParserProtocole.protocole LexerProtocole.lexem_list buff)
  with
  | Parsing.Parse_error -> None
  | Failure _ -> None

let split_gen sep s = 
  let len = String.length s in
  let q = Queue.create () in
  let rec aux accu i =
    if i >= len
    then
      begin
        (
          if accu <> ""
          then Queue.push accu q
          else ()
        )
        ;
        let argc = Queue.length q in (argc, Array.init argc (fun _ -> Queue.pop q))
      end
    else
      if s.[i] = sep
      then (Queue.push accu q; aux "" (succ i))
      else (aux (Printf.sprintf "%s%c" accu s.[i]) (succ i))
  in 
  if len > 0
  then aux "" 0
  else (0, [||]);;



let reponse_of_string s =
  let (num, tab) = split_gen ' ' s in
  match num with
  | 1 -> 
      if tab.(0).[0] = '$'
      then 
	let len = String.length tab.(0) in
	try
	  Some (Asynchrone (int_of_string (String.sub tab.(0) 1 (pred len)), ""))
	with
	| _ -> None
      else Some (Synchrone tab.(0))
  | 2 ->
      begin
	if tab.(0).[0] = '$'
	then
	  let len = String.length tab.(0) in
	  try
	    Some (Asynchrone (int_of_string (String.sub tab.(0) 1 (pred len)), tab.(1)))
	  with
	  | _ -> None
	else None
      end
  | _ -> None

